#include "AppStateGame.h"
#include "AppStateManager.h"
#include <sstream>
#include <algorithm>


void CAppStateGame::OnKeyDownInterface(SDLKey sym)
{
	if( sym == JumpKey)
	{
		//Send key input to server
		if(CEntity::PlayerList.at(CClient::myID)->CanJump)
			CClient::getInstance().SendPacket(0,0,0,2);
	}
	else if (sym == LeftKey) 
	{
		//Send key input to server
		if(!CEntity::PlayerList.at(CClient::myID)->MoveLeft)
			CClient::getInstance().SendPacket(0,0,0,0);
	}
	else if( sym == RightKey) 
	{
		//Send key input to server
		if(!CEntity::PlayerList.at(CClient::myID)->MoveRight)
			CClient::getInstance().SendPacket(0,0,0,1);
	}

	else if( sym ==  SDLK_ESCAPE)
	{
		//change appstate to lobby
		CAppStateManager::SetActiveAppState(APPSTATE_LOBBY);
	}
	else if(sym == SDLK_F1)
	{
		//allows showing helpscreen
		helpScreenON = true;
	}
	else if(sym == SDLK_TAB)
	{
		//allows showing scorescreen
		tabScreenON = true;	
		itemScreenON = false;
	}

	else if(sym == SDLK_i)
	{
	
		tabScreenON = false;
		itemScreenON = true;
	}
}

void CAppStateGame::OnKeyUpInterface(SDLKey sym)
{
	if (sym == LeftKey) 
	{
		// packetID 0 for a game command packet, entityID 0, playerID is set in the function itself atm, command 4 stop moving left.
		CClient::getInstance().SendPacket(0,0,0,3);
		CEntity::PlayerList.at(CClient::myID)->MoveLeft = false;
	}
	else if( sym == RightKey) 
	{
		// packetID 0 for a game command packet, entityID 0, playerID is set in the function itself atm, command 4 stop moving right.
			CClient::getInstance().SendPacket(0,0,0,4);
			CEntity::PlayerList.at(CClient::myID)->MoveRight = false;
	}
	else if(sym == SDLK_TAB)
	{
		//hides scorescreen
		tabScreenON = false;
	}
	else if(sym == SDLK_i)
	{
		itemScreenON = false;
	}
	else if(sym == SpellHotKey1)
	{
		if(SDL_GetTicks() > CEntity::PlayerList.at(CClient::myID)->castSpell1)
		{
			cIconRect.x = (WWIDTH/3) + (WWIDTH/16) - 2;
			IconNameDisplay = "FireBall Spell";
			if(!CEntity::PlayerList.at(CClient::myID)->casting)
				CClient::getInstance().SendPacket(0,4,0,6, CEntity::mouseX+CCamera::CameraControl.GetX(), CEntity::mouseY+CCamera::CameraControl.GetY());
			
		}
	}
	else if(sym == SDLK_F1)
	{
		//hides helpscreen
		helpScreenON = false;
	}

	if(sym == SpellHotKey2)
	{
		if(SDL_GetTicks() > CEntity::PlayerList.at(CClient::myID)->castSpell2)
		{
			cIconRect.x = (WWIDTH/3) + (WWIDTH/16) + 48;
			IconNameDisplay = "MagicMissile Spell";
			if(!CEntity::PlayerList.at(CClient::myID)->casting)
				CClient::getInstance().SendPacket(0,5,0,6, CEntity::mouseX+CCamera::CameraControl.GetX(), CEntity::mouseY+CCamera::CameraControl.GetY());
		}
	}
	if(sym == SpellHotKey3)
	{
		if(SDL_GetTicks() > CEntity::PlayerList.at(CClient::myID)->castSpell3)
		{
			cIconRect.x = (WWIDTH/3) + (WWIDTH/16) + 98;
			IconNameDisplay = "Frost Spell";
			if(!CEntity::PlayerList.at(CClient::myID)->casting)
				CClient::getInstance().SendPacket(0,2,0,6, CEntity::mouseX+CCamera::CameraControl.GetX(), CEntity::mouseY+CCamera::CameraControl.GetY());
		}
	}
	if(sym == SpellHotKey4)
	{
		if(SDL_GetTicks() > CEntity::PlayerList.at(CClient::myID)->castSpell4)
		{
			cIconRect.x = (WWIDTH/3) + (WWIDTH/16) + 148;
			IconNameDisplay = "Flash Spell";
			if(!CEntity::PlayerList.at(CClient::myID)->casting)
				CClient::getInstance().SendPacket(0,3,0,6, CEntity::mouseX+CCamera::CameraControl.GetX(), CEntity::mouseY+CCamera::CameraControl.GetY());
		}
	}
	if(sym == SpellHotKey5)
	{
		if(SDL_GetTicks() > CEntity::PlayerList.at(CClient::myID)->castSpell5)
		{
			cIconRect.x = (WWIDTH/3) + (WWIDTH/16) + 198;
			IconNameDisplay = "Disrupt Spell";
			if(!CEntity::PlayerList.at(CClient::myID)->casting)
				CClient::getInstance().SendPacket(0,1,0,6, CEntity::mouseX+CCamera::CameraControl.GetX(), CEntity::mouseY+CCamera::CameraControl.GetY());
		}
	}
	if(sym == OffensiveSpellKey)
	{
		// packetID 0 for a game command packet, entityID 0, playerID is set in the function itself atm, command 6 for casting projectile Q.
		// need to rewrite, so that target coordinates are sent upon spell finish, for dynamic aiming with your mouse, rather than having to select
		// direction when you click.
		char c[20] = "NULL";
		//CClient::getInstance().SendPacket(0,0,0,6, CEntity::mouseX+CCamera::CameraControl.GetX(), CEntity::mouseY+CCamera::CameraControl.GetY());
	}
	else if( sym == SDLK_RETURN)
	{
	}
}

bool CAppStateGame::my_cmp(const scores& a, const scores& b)
{
	 return a.score < b.score;
}

void CAppStateGame::OnRenderInterface(SDL_Surface* Surf_Display)
{
	SDL_Rect Rect;
	Rect.x = 0;
	Rect.y = 0;
	Rect.w = 20;
	Rect.h = 20;

	SDL_Rect CastRect;
	CastRect.x = WWIDTH/2 - 75;
	CastRect.y = (WHEIGHT/2)+(WHEIGHT/4);
	CastRect.w = 0;
	CastRect.h = 20;

		// Cast bar
	if(CEntity::PlayerList.at(CClient::myID)->casting)
	{
		int vlad = (SDL_GetTicks());
		if(CEntity::PlayerList.at(CClient::myID)->castEnd >= vlad && CEntity::PlayerList.at(CClient::myID)->castStart <= vlad)
		{	
			temp2 = ((((double)vlad-(double)CEntity::PlayerList.at(CClient::myID)->castStart)/((double)CEntity::PlayerList.at(CClient::myID)->castEnd - (double)CEntity::PlayerList.at(CClient::myID)->castStart))*100.0);
			CastRect.w = (1.5)*temp2;
			SDL_FillRect(Surf_Display, &CastRect, 255255);
		}
	}
	//Health bar
	Rect.x = WWIDTH/8;
	Rect.y = (WHEIGHT/2)+(WHEIGHT/4)+80;
	Rect.w = ((CEntity::PlayerList.at(CClient::myID)->health * 100)/100);
	SDL_FillRect(Surf_Display, &Rect, 255255255255555);
		
	//Spell menu
	SDL_FillRect(Surf_Display, &cIconRect, 25525525525555);

	SDL_Rect IconRect;
	IconRect.x = xCalcIcons;
	IconRect.y = yCalcIcons;
	IconRect.h = 32;
	IconRect.w = 32;
	SDL_BlitSurface(fireBallIcon, NULL, Surf_Display, &IconRect);

	IconRect.x = xCalcIcons + 50;
	SDL_BlitSurface(magicMissileIcon, NULL, Surf_Display, &IconRect);

	IconRect.x = xCalcIcons + 100;
	SDL_BlitSurface(frostIcon, NULL, Surf_Display, &IconRect);

	IconRect.x = xCalcIcons + 150;
	SDL_BlitSurface(shieldIcon, NULL, Surf_Display, &IconRect);

	IconRect.x = xCalcIcons + 200;
	SDL_BlitSurface(disruptIcon, NULL, Surf_Display, &IconRect);

	//Items
	SDL_Surface* Text_SolidItems;
	SDL_Rect TextPosItems;
	SDL_Rect TextPosEffects;
	SDL_Colour black = {0,0,0};
	SDL_Rect itemBar;

	////Spell / ability Text
	SDL_Rect spellTxt;
	SDL_Surface* SpellText;
	SpellText = NULL;
	spellTxt.x = WWIDTH/2 - IconNameDisplay.size()*2 - 35;
	spellTxt.y = yCalcIcons - 30;
	SDL_Colour red = {0,0,0};
	SpellText = TTF_RenderText_Blended(font, IconNameDisplay.c_str(), red);
	SDL_BlitSurface(SpellText, NULL, Surf_Display, &spellTxt);
	SDL_FreeSurface(SpellText);

	//HPText
	SDL_Rect hpRct;
	SDL_Surface* HPText;
	hpRct.x = WWIDTH/8 + 2;
	hpRct.y = (WHEIGHT/2)+(WHEIGHT/4)+80;
	std::stringstream out;
	out << CEntity::PlayerList.at(CClient::myID)->health;
	std::string HPstring = out.str();
	out.str(std::string());
	HPText = TTF_RenderText_Blended(font, HPstring.c_str(), red);
	SDL_BlitSurface(HPText, NULL, Surf_Display, &hpRct);
	SDL_FreeSurface(HPText);
		
	//TabScreen
	if(tabScreenON)
	{
		SDL_Rect tabRect;
		SDL_Rect TextPos;
		tabRect.x = xCalcIcons - 80;
		tabRect.y = yCalcIcons - 420;
		tabRect.h = 264;
		tabRect.w = 319;
		SDL_BlitSurface(tabScreen, NULL, Surf_Display, &tabRect);
		SDL_Rect scoreBar;
		std::vector<scores> score;
		Uint32 color;

		for(int i = 0; i < CEntity::PlayerList.size(); i++)
		{	
			scores s;
			s.name = CEntity::PlayerList.at(i)->name;
			s.score = CEntity::PlayerList.at(i)->playerScore;
			s.deaths = CEntity::PlayerList.at(i)->playerDeaths;
			score.push_back(s);
				
		}
			
			std::sort(score.rbegin(), score.rend(),my_cmp);
		for(int i = 0; i < CEntity::PlayerList.size(); i++)
		{
			if(i==2)
			{
				color = SDL_MapRGB(Surf_Display->format, 166, 125, 61);
			}
			else if(i==1)
			{
				color = SDL_MapRGB(Surf_Display->format, 230, 232, 250);
			}
			else if(i==0)
			{
				color = SDL_MapRGB(Surf_Display->format, 217, 217, 25);
			}
			else
			{
				color = SDL_MapRGB(Surf_Display->format, 192, 192, 192);
			}
			SDL_Surface* Text_Solid;
			TextPos.x = xCalcIcons - 47;
			TextPos.y = (yCalcIcons - 440) + (i*23+40);

			scoreBar.x = xCalcIcons - 50;
			scoreBar.y = (yCalcIcons - 437) + (i*23+40);
			scoreBar.w = 210;
			scoreBar.h = 20;
				
				
			SDL_FillRect(Surf_Display, &scoreBar, color);	

			Text_Solid = TTF_RenderText_Blended(font, score.at(i).name.c_str(), black);
			SDL_BlitSurface(Text_Solid, NULL, Surf_Display, &TextPos);
			SDL_FreeSurface(Text_Solid);

				
			TextPos.x = xCalcIcons+5;
			TextPos.y = (yCalcIcons - 440) + (i*23+40);
			out <<  score.at(i).score;
			std::string output = out.str();
			Text_Solid = TTF_RenderText_Blended(font,output.c_str(), black);
			SDL_BlitSurface(Text_Solid, NULL, Surf_Display, &TextPos);
			SDL_FreeSurface(Text_Solid);
			out.str(std::string());
				
			TextPos.x = xCalcIcons + 95;
			TextPos.y = (yCalcIcons - 440) + (i*23+40);
			out << score.at(i).deaths;
			output = out.str();
			Text_Solid = TTF_RenderText_Blended(font,output.c_str(), black);
			SDL_BlitSurface(Text_Solid, NULL, Surf_Display, &TextPos);
			SDL_FreeSurface(Text_Solid);
			out.str(std::string());
		}	
	}

	//HelpScreen
	if(helpScreenON)
	{
		SDL_Rect helpRect;
		helpRect.x = xCalcIcons - 200;
		helpRect.y = yCalcIcons - 280;
		helpRect.h = 173;
		helpRect.w = 510;
		SDL_BlitSurface(helpScreen, NULL, Surf_Display, &helpRect);

		//Draw sdlkey text
		SDL_Surface* Text_SolidSurface;
		
		Rect.x = 85;
		Rect.y = 185;
		Text_SolidSurface = OnRenderSDLKey(LeftKey);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.y = 220;
		Text_SolidSurface = OnRenderSDLKey(RightKey);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.y = 260;
		Text_SolidSurface = OnRenderSDLKey(JumpKey);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.y = 300;
		Text_SolidSurface = OnRenderSDLKey(SpellHotKey1);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.x = 235;
		Rect.y = 185;
		Text_SolidSurface = OnRenderSDLKey(OffensiveSpellKey);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.y = 220;
		Text_SolidSurface = OnRenderSDLKey(FlySpellKey);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.y = 300;
		Text_SolidSurface = OnRenderSDLKey(SpellHotKey2);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.x = 390;
		Rect.y = 185;
		Text_SolidSurface = OnRenderSDLKey(DefensiveSpellKey);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.y = 220;
		Text_SolidSurface = OnRenderSDLKey(UtilitySpellKey);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);

		Rect.y = 300;
		Text_SolidSurface = OnRenderSDLKey(SpellHotKey3);
		SDL_BlitSurface(Text_SolidSurface, NULL, Surf_Display, &Rect);
		SDL_FreeSurface(Text_SolidSurface);
	}

	if(itemScreenON)
	{
		
		Uint32 color;
		color = SDL_MapRGB(Surf_Display->format, 192, 192, 192);
		std::string items[5];
		std::string effect;
		items[0] = CEntity::PlayerList.at(CClient::myID)->itemArray[0];
		items[0] = itemclass.names[atoi(items[0].c_str())];
		items[1] = CEntity::PlayerList.at(CClient::myID)->itemArray[1];
		items[1] = itemclass.names[atoi(items[1].c_str())];
		items[2] = CEntity::PlayerList.at(CClient::myID)->itemArray[2];
		items[2] = itemclass.names[atoi(items[2].c_str())];
		items[3] = CEntity::PlayerList.at(CClient::myID)->itemArray[3];
		items[3] = itemclass.names[atoi(items[3].c_str())];
		items[4] = CEntity::PlayerList.at(CClient::myID)->itemArray[4];
		items[4] = itemclass.names[atoi(items[4].c_str())];

		SDL_Rect tabRect;
		tabRect.x = xCalcIcons - 80;
		tabRect.y = yCalcIcons - 420;
		tabRect.h = 264;
		tabRect.w = 319;
		
		SDL_BlitSurface(itemScreen, NULL, Surf_Display, &tabRect);

		for(int i = 0; i < 5; i++)
		{
			itemBar.x = xCalcIcons - 50;
			itemBar.y = (yCalcIcons - 437) + (i*23+40);
			itemBar.w = 210;
			itemBar.h = 20;		
			SDL_FillRect(Surf_Display, &itemBar, color);	
			Text_SolidItems = TTF_RenderText_Blended(font, items[i].c_str(), black);
			TextPosItems.x = xCalcIcons - 47;
			TextPosItems.y = (yCalcIcons - 440) + (i*23+40);
			TextPosEffects.x = xCalcIcons + 90;
			TextPosEffects.y = (yCalcIcons - 434) + (i*23+40);
			SDL_BlitSurface(Text_SolidItems, NULL, Surf_Display, &TextPosItems);
			SDL_FreeSurface(Text_SolidItems);
			effect = CEntity::PlayerList.at(CClient::myID)->itemArray[i];
			effect = itemclass.effects[atoi(effect.c_str())];
			effect[3]+= 'H'; 
			effect[7]+= 'C';
			effect[11]+= 'm';
			effect[12] = NULL;
				
			Text_SolidItems = TTF_RenderText_Blended(CSurface::font, effect.c_str(), black);
			SDL_BlitSurface(Text_SolidItems, NULL, Surf_Display, &TextPosEffects);
			SDL_FreeSurface(Text_SolidItems);
		}
	}
}

void CAppStateGame::OnLoopInterface()
{

}

//Convert sdlkeys to plain text
SDL_Surface* CAppStateGame::OnRenderSDLKey(SDLKey input)
{
	std::string text;
	SDL_Colour black = {0,0,0};
	if(input == SDLK_SPACE)
		text = "space";
	else if(input == SDLK_RETURN)
		text = "enter";
	else if(input == SDLK_LEFT)
		text = "left";
	else if(input == SDLK_RIGHT)
		text = "right";
	else if(input == SDLK_UP)
		text = "up";
	else if(input == SDLK_DOWN)
		text = "down";
	else if(input == SDLK_PERIOD)
		text = ".";
	else if(input == SDLK_LSHIFT || input == SDLK_RSHIFT)
		text = "shift";
	else if(input == SDLK_RCTRL || input == SDLK_RCTRL)
		text = "ctrl";
	else if(input == SDLK_RALT || input == SDLK_RALT)
		text = "alt";
	else
		text = input;
		
	return TTF_RenderText_Blended(font, text.c_str(), black);
}